#include <accelerometer.h>
#include <display.h>
#include <h01.h>
#include <iic.h>

uint	timer;
ushort	error;

static ubyte	fifo,tap,tapfifo;

static void initClock(void){
	SystemCoreClockUpdate();
	RCC_APB1PeriphClockCmd(
		RCC_APB1Periph_BKP|
		RCC_APB1Periph_I2C2|
		RCC_APB1Periph_PWR,ENABLE);
	RCC_APB2PeriphClockCmd(
		RCC_APB2Periph_AFIO|
		RCC_APB2Periph_GPIOA|
		RCC_APB2Periph_GPIOB|
		RCC_APB2Periph_GPIOC|
		RCC_APB2Periph_TIM1,ENABLE);
	PWR_BackupAccessCmd(ENABLE);
}
static void initNVIC(void){
	NVIC_SetVectorTable(NVIC_VectTab_FLASH,0);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

	NVIC_InitTypeDef n;
	n.NVIC_IRQChannel=EXTI0_IRQn;		// WKUP
	n.NVIC_IRQChannelPreemptionPriority=2;
	n.NVIC_IRQChannelSubPriority=1;
	n.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&n);
	n.NVIC_IRQChannel=EXTI15_10_IRQn;	// GSINT
	n.NVIC_IRQChannelPreemptionPriority=2;
	n.NVIC_IRQChannelSubPriority=1;
	n.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&n);
	n.NVIC_IRQChannel=I2C2_EV_IRQn;		// IIC2
	n.NVIC_IRQChannelPreemptionPriority=0;
	n.NVIC_IRQChannelSubPriority=0;
	n.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&n);
	EXTI_DeInit();
	EXTI_InitTypeDef x;
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,PINSRC_WKUP);
	x.EXTI_Line	  =EXTI_WKUP;
	x.EXTI_Mode	  =EXTI_Mode_Interrupt;
	x.EXTI_Trigger=EXTI_Trigger_Falling;
	x.EXTI_LineCmd=ENABLE;
	EXTI_Init(&x);
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,PINSRC_GSINT);
	x.EXTI_Line	  =EXTI_GSINT;
	x.EXTI_Mode	  =EXTI_Mode_Interrupt;
	x.EXTI_Trigger=EXTI_Trigger_Falling;
	x.EXTI_LineCmd=ENABLE;
	EXTI_Init(&x);
	NVIC_SetPriority(SysTick_IRQn,1);
	//if(SystemCoreClock!=72000000)
	//	errorcode |= ERROR_SYSCLK_UEQ_72M;
}
static void initGPIO(void){
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);   //Use SWD
	GPIO_InitTypeDef g;
	g.GPIO_Speed=GPIO_Speed_50MHz;

	g.GPIO_Pin	=PIN_CHIN;
	g.GPIO_Mode	=GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA,&g);
	g.GPIO_Pin	=PIN_CHOUT;
	g.GPIO_Mode	=GPIO_Mode_Out_OD;
	GPIO_SetBits(GPIOA,g.GPIO_Pin);
	GPIO_Init(GPIOA,&g);
	g.GPIO_Pin	=PIN_Y0_Y2;
	g.GPIO_Mode	=GPIO_Mode_Out_PP;
	GPIO_ResetBits(GPIOA,g.GPIO_Pin);
	GPIO_Init(GPIOA,&g);
    g.GPIO_Pin	=PIN_WKUP;
    g.GPIO_Mode	=GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA,&g);

    g.GPIO_Pin	=PIN_GSINT;
    g.GPIO_Mode	=GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOB,&g);
	g.GPIO_Pin	=PIN_Y3_Y9;
	g.GPIO_Mode	=GPIO_Mode_Out_PP;
	GPIO_ResetBits(GPIOB,g.GPIO_Pin);
	GPIO_Init(GPIOB,&g);
	g.GPIO_Pin	=PIN_I2C;
	g.GPIO_Mode	=GPIO_Mode_AF_OD;
	GPIO_SetBits(GPIOB,g.GPIO_Pin);
	GPIO_Init(GPIOB,&g);

	g.GPIO_Pin	=PIN_X0_Y9;
	g.GPIO_Mode	=GPIO_Mode_Out_OD;
	GPIO_SetBits(GPIOC,g.GPIO_Pin);
	GPIO_Init(GPIOC,&g);
}

static void initAccelerometer(void){
	static ubyte ctrl[]={
		0x47,				// 50-Hz, enable x-y-z
		0xb5,				// hp-filter on tap
		0x02,				// fifo overrun on int1
		0x10,				// continuos update, lsb, 4g
		0x40,				// fifo on, int not latched
		0x82				// tap enabled, h-l active
	};
	static ubyte int1[]={
		0x00,				//
		0,					// dummy of source
		0x04,				// int1 threshold
		0x01,				// int1 duration
	};
	static ubyte fifo[2]={
		0,					// reset fifo
		0x80				// stream mode
	};
	static ubyte tap[]={
		0x15,				// x-y-z single tapup
		0,					// dummy of source
		0x3f,				// tap threshold
		0x01,				// timelimit
	};
	initIIC();
	writeIIC(ADD_ACC,REG_CTRL1|0x80,ctrl,6);
	writeIIC(ADD_ACC,REG_INTCFG|0x80,int1,4);
	writeIIC(ADD_ACC,REG_FIFOCTRL,fifo,2);
	writeIIC(ADD_ACC,REG_TAPCFG|0x80,tap,4);
}
static void readAccelerometer(void){
	int i=0;
	for(;;i++){
		ubyte b[6];
		readIIC(ADD_ACC,REG_FIFOSRC,b,1);
		if(b[0]&0x20)
			break;
		readIIC(ADD_ACC,REG_OUTXL|0x80,b,6);
	}
	outDec(i);
}

//------------------------------------------------------------------------------

void EXTI0_IRQHandler(void){
	if(EXTI_GetITStatus(EXTI_WKUP)!=RESET){
		EXTI_ClearITPendingBit(EXTI_WKUP);
		fifo=1;
	}
}
void EXTI15_10_IRQHandler(void){
	if(EXTI_GetITStatus(EXTI_GSINT)!=RESET){
		tap=1;
		tapfifo=!tapfifo;
		EXTI_ClearITPendingBit(EXTI_GSINT);
	}
}

//------------------------------------------------------------------------------

void main(void){
	initClock();
	initNVIC();
	initGPIO();
	initAccelerometer();
	while(1){
		if(tapfifo)
			readAccelerometer();
		if(fifo){
			readAccelerometer();
			displayOn();
			outHex(0xabcde);
			fifo=0;
			timer=0;
		}else if(tap){
			displayOn();
			outBar(19);
			tap=0;
			timer=0;
		}
		if(timer<200)
			__WFI();
		else{
			displayOff();
			PWR_EnterSTOPMode(PWR_Regulator_ON,PWR_STOPEntry_WFI);
			SystemInit();
		}
	}
}